package com.avecsys.quotemanager.utils;

/**
 * @author Sam Sundar
 * 
 */
public class ByteArrayUtils {

	/**
	 * Convert a hexadecimal string into it byte array representation.
	 * 
	 * @param input
	 *            The string to be converted.
	 * @return The byte array result of the conversion, or null if the string
	 *         passed in the parameter is null or is not a hexadecimal string.
	 */
	public static byte[] hexStringToByteArray(String input) {
		byte[] result = null;
		if (input != null) {
			if (isHexString(input)) {
				int len = input.length();
				result = new byte[len / 2];
				int arrayIndex = 0;
				for (int tempCtr = 0; tempCtr < len; tempCtr += 2, arrayIndex++) {
					String twoDigits = input.substring(tempCtr, tempCtr + 2);
					result[arrayIndex] = (byte) Integer.parseInt(twoDigits, 16);
				}
			}
		}
		return result;
	}

	/**
	 * Convert a byte array to its hexadecimal string representation.
	 * 
	 * @param input
	 *            The byte array to be converted
	 * @return The hexadecimal string result of the conversion or null if the
	 *         byte array passed in the parameter is null.
	 */
	public static String byteArrayToHexString(byte[] input) {
		if (input != null) {
			int len = input.length;
			StringBuffer byteStringBuffer = new StringBuffer(len);
			for (int i = 0; i < len; i++) {
				byteStringBuffer.append(byteToHexString(input[i]));
			}
			return byteStringBuffer.toString();
		}
		return null;
	}

	/**
	 * Convert a byte array to its hexadecimal string representation.
	 * 
	 * @param input
	 *            The byte array to be converted
	 * @param offset
	 *            The offset where conversion shall start
	 * @param length
	 *            The length of data for the conversion
	 * @return The hexadecimal string result of the conversion or null if the
	 *         byte array passed in the parameter is null.
	 */
	public static String byteArrayToHexString(byte[] input, int offset,
			int length) {
		if (input != null) {
			if ((offset >= 0) && (length >= 0)) {
				int len = input.length;
				if ((offset + length) <= len) {
					StringBuffer byteStringBuffer = new StringBuffer(len);
					for (int i = offset; i < offset + length; i++) {
						byteStringBuffer.append(byteToHexString(input[i]));
					}
					return byteStringBuffer.toString();
				}
				return null;
			}
			return null;
		}
		return null;
	}

	/**
	 * Convert a byte array to its hexadecimal string representation, separating
	 * its byte representation with the given delimiter
	 * 
	 * @param input
	 *            The byte array to be converted
	 * @param delimiter
	 *            The delimiter for each byte string representation
	 * @return The hexadecimal string result of the conversion or null if the
	 *         byte array passed in the parameter is null.
	 */
	public static String byteArrayToDelimitedHexString(byte[] input,
			char delimiter) {
		if (input != null) {
			int len = input.length;
			StringBuffer byteStringBuffer = new StringBuffer(len);
			for (int i = 0; i < len; i++) {
				byteStringBuffer.append(byteToHexString(input[i]));
				if (i + 1 < len) {
					byteStringBuffer.append(delimiter);
				}
			}
			return byteStringBuffer.toString();
		}
		return null;
	}

	/**
	 * Convert a single byte value to its hexadecimal string representation.
	 * 
	 * @param value
	 *            The byte value to be converted.
	 * @return The hexadecimal string conversion result.
	 */
	public static String byteToHexString(byte value) {
		String byteString = Integer.toHexString(value).toUpperCase();
		int len = byteString.length();
		byteString = (len == 8) ? byteString.substring(6) : byteString;
		byteString = (len == 1) ? "0" + byteString : byteString; //$NON-NLS-1$
		return byteString;
	}

	/**
	 * Perform a conversion of a 2-characters hexadecimal string to a byte.
	 * 
	 * @param hexString
	 *            The 2-characters hexadecimal string to be converted. If the
	 *            string is empty then 0x00 is returned. If the string is longer
	 *            than 2 character then the conversion will only convert based
	 *            on the first 2 characters of the string.
	 * @return The byte value result of the conversion.
	 * @throws NumberFormatException
	 * @throws NullPointerException
	 */
	public static byte hexStringToByte(String hexString)
			throws NumberFormatException, NullPointerException {
		byte result = (byte) Integer.parseInt(hexString.substring(0, 2), 16);
		return result;
	}

	public static boolean isHexString(String input) {
		if ((input.length() % 2) == 0) {
			byte[] array = input.getBytes();
			int len = input.length();
			for (int i = 0; i < len; i++) {
				if (((array[i] >= 0x30) && (array[i] <= 0x39))
						|| ((array[i] >= 0x41) && (array[i] <= 0x46))
						|| ((array[i] >= 0x61) && (array[i] <= 0x66))) {
					continue;
				}
				return false;
			}
			return true;
		}
		return false;
	}
}
